"""

.. module:: http

The purpose of this module is to handle the A2P HTTP requests to and responses
from Spear.
   
*Constants*:

.. seealso:: modules :mod:`<module>`
"""

# Imports
#
import cookielib
import logging
import urllib
import urllib2

from runtime.node import LoggingLevels

# Constants
#

# Classes
#

class HTTP(object):
    """
    This class handles the HTTP requests for A2P. 

    **Constants**:
    """
    
    # Class constants
    #

    def __init__(self):
        # Constructor.
        #
        
        # We need to get our Cookie Jar installed in the opener for fetching URLS.
        #
        self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookielib.LWPCookieJar()))
        self.logger = logging.getLogger()
    
    def issue_request(self, theurl, data_dict=None):
        """
        This function creates and issues the HTTP request to the argument 'url'.
        If 'data_dict' is provided then it is encoded and sent in a POST request.
        Otherwise a GET request is sent.
        
        :param theurl: String
        :param data_dict: dictionary
        :rtype: tuple(HTTP code, HTML String)
        """
        
        self.logger.log(LoggingLevels.TRACE, "theurl(%s), data_dict(%s)" % (theurl, data_dict))
        
        try:
            # create a request object. If 'data_dict' is None then a GET request will
            # be created. Otherwise a POST is created.
            #
            if (data_dict is not None) and (len(data_dict) > 0):
                # We require 'Content-Type' header if sending a POST. urllib.urlencode()
                # returns the data in 'application/x-www-form-urlencoded' form.
                #
                txheaders = {'Content-Type': 'application/x-www-form-urlencoded'}
                txdata = urllib.urlencode(data_dict) 
                req = urllib2.Request(theurl, txdata, txheaders)
            else:
                txheaders = {}
                req = urllib2.Request(theurl, None, txheaders)
            
            # send the request and get a handle to the response.
            #
            handle = self.opener.open(req)
            
            self.logger.log(LoggingLevels.TRACE, 'Requested Url (%s)' % theurl)
            self.logger.log(LoggingLevels.TRACE, 'Fetched Url (%s)' % handle.geturl())
            self.logger.log(LoggingLevels.TRACE, 'Response Code (%s)' % handle.code)
        except IOError as e:
            self.logger.log(logging.ERROR, 'Error making HTTP request (%s).' % theurl)

            if (hasattr(e, 'code')):
                self.logger.log(logging.ERROR, 'Error code (%s)' % e.code)
            if (hasattr(e, 'reason')):
                self.logger.log(logging.ERROR, 'Error reason (%s)' % e.reason)
            
            self.logger.log(logging.ERROR, 'Error (%s)' % e)
            
            return (-1, "", "")
        
        # (in case urlopen has followed any redirects, which it sometimes does)
        #           
        return (handle.code, handle.geturl(), handle.read())